/* Save a structured n x n mesh of square elements on the unit square into a
   GLVis mesh file with the given name. */
void GLVis_PrintGlobalSquareMesh(const char *meshfile, int n)
{
   FILE *file;

   int Dim = 2;
   int NumOfVertices = (n+1)*(n+1);
   int NumOfElements = n*n;

   int i, j;
   double x, y;
   double h = 1.0/n;

   if ((file = fopen(meshfile, "w")) == NULL)
   {
      printf("Error: can't open output file %s\n", meshfile);
      exit(1);
   }

   /* mesh header */
   fprintf(file, "MFEM mesh v1.0\n");
   fprintf(file, "\ndimension\n");
   fprintf(file, "%d\n", Dim);

   /* mesh elements */
   fprintf(file, "\nelements\n");
   fprintf(file, "%d\n", NumOfElements);
   for (j = 0; j < n; j++)
      for (i = 0; i < n; i++)
         fprintf(file, "1 3 %d %d %d %d\n", i + j*(n+1), i + 1 +j*(n+1),
                 i + 1 + (j+1)*(n+1), i + (j+1)*(n+1));

   /* boundary will be generated by GLVis */
   fprintf(file, "\nboundary\n");
   fprintf(file, "0\n");

   /* mesh vertices */
   fprintf(file, "\nvertices\n");
   fprintf(file, "%d\n", NumOfVertices);
   fprintf(file, "%d\n", Dim);
   for (j = 0; j < n+1; j++)
      for (i = 0; i < n+1; i++)
      {
         x = i*h;
         y = j*h;
         fprintf(file, "%.14e %.14e\n", x, y);
      }

   fflush(file);
   fclose(file);
}

/* Save a structured nx x ny mesh of square elements of size h, globally
   translated by (x0,y0), into a GLVis mesh file with the given prefix. */
void GLVis_PrintLocalSquareMesh(const char *meshfile_prefix, int nx, int ny,
                                double h, double x0, double y0, int myid)
{
   FILE *file;
   char meshfile[255];

   int Dim = 2;
   int NumOfVertices = (nx+1)*(ny+1);
   int NumOfElements = nx*ny;

   int i, j;
   double x, y;

   sprintf(meshfile, "%s.%06d", meshfile_prefix, myid);
   if ((file = fopen(meshfile, "w")) == NULL)
   {
      printf("Error: can't open output file %s\n", meshfile);
      exit(1);
   }

   /* mesh header */
   fprintf(file, "MFEM mesh v1.0\n");
   fprintf(file, "\ndimension\n");
   fprintf(file, "%d\n", Dim);

   /* mesh elements */
   fprintf(file, "\nelements\n");
   fprintf(file, "%d\n", NumOfElements);
   for (j = 0; j < ny; j++)
      for (i = 0; i < nx; i++)
         fprintf(file, "1 3 %d %d %d %d\n", i + j*(nx+1), i + 1 +j*(nx+1),
                 i + 1 + (j+1)*(nx+1), i + (j+1)*(nx+1));

   /* boundary will be generated by GLVis */
   fprintf(file, "\nboundary\n");
   fprintf(file, "0\n");

   /* mesh vertices */
   fprintf(file, "\nvertices\n");
   fprintf(file, "%d\n", NumOfVertices);
   fprintf(file, "%d\n", Dim);
   for (j = 0; j < ny+1; j++)
      for (i = 0; i < nx+1; i++)
      {
         x = x0+i*h;
         y = y0+j*h;
         fprintf(file, "%.14e %.14e\n", x, y);
      }

   fflush(file);
   fclose(file);
}

/* Save a structured n x n mesh of gamma-angled rhombuses, globally rotated by
   angle gamma*myid, into a GLVis mesh file with the given prefix. */
void GLVis_PrintLocalRhombusMesh(const char *meshfile_prefix,
                                 int n, int myid, double gamma)
{
   FILE *file;
   char meshfile[255];

   int Dim = 2;
   int NumOfVertices = (n+1)*(n+1);
   int NumOfElements = n*n;

   int i, j;
   double x, y;
   double h = 1.0/n;

   double rho = gamma*myid;
   double sg  = sin(gamma);
   double cg  = cos(gamma);
   double sr  = sin(rho);
   double cr  = cos(rho);

   sprintf(meshfile, "%s.%06d", meshfile_prefix, myid);
   if ((file = fopen(meshfile, "w")) == NULL)
   {
      printf("Error: can't open output file %s\n", meshfile);
      exit(1);
   }

   /* mesh header */
   fprintf(file, "MFEM mesh v1.0\n");
   fprintf(file, "\ndimension\n");
   fprintf(file, "%d\n", Dim);

   /* mesh elements */
   fprintf(file, "\nelements\n");
   fprintf(file, "%d\n", NumOfElements);
   for (j = 0; j < n; j++)
      for (i = 0; i < n; i++)
         fprintf(file, "1 3 %d %d %d %d\n", i + j*(n+1), i + 1 +j*(n+1),
                 i + 1 + (j+1)*(n+1), i + (j+1)*(n+1));

   /* boundary will be generated by GLVis */
   fprintf(file, "\nboundary\n");
   fprintf(file, "0\n");

   /* mesh vertices */
   fprintf(file, "\nvertices\n");
   fprintf(file, "%d\n", NumOfVertices);
   fprintf(file, "%d\n", Dim);
   for (j = 0; j < n+1; j++)
      for (i = 0; i < n+1; i++)
      {
         x = i*h + cg*j*h;
         y = sg*j*h;
         fprintf(file, "%.14e %.14e\n", cr*x - sr*y, sr*x + cr*y);
      }

   fflush(file);
   fclose(file);
}

/* Save a structured nx x ny x nz mesh of cubic elements of size h, globally
   translated by (x0,y0,z0), into a GLVis mesh file with the given prefix. */
void GLVis_PrintLocalCubicMesh(const char *meshfile_prefix,
                               int nx, int ny, int nz, double h,
                               double x0, double y0, double z0, int myid)
{
   FILE *file;
   char meshfile[255];

   int Dim = 3;
   int NumOfVertices = (nx+1)*(ny+1)*(nz+1);
   int NumOfElements = nx*ny*nz;

   int i, j, k;
   double x, y, z;

   sprintf(meshfile, "%s.%06d", meshfile_prefix, myid);
   if ((file = fopen(meshfile, "w")) == NULL)
   {
      printf("Error: can't open output file %s\n", meshfile);
      exit(1);
   }

   /* mesh header */
   fprintf(file, "MFEM mesh v1.0\n");
   fprintf(file, "\ndimension\n");
   fprintf(file, "%d\n", Dim);

   /* mesh elements */
   fprintf(file, "\nelements\n");
   fprintf(file, "%d\n", NumOfElements);
   for (k = 0; k < nz; k++)
      for (j = 0; j < ny; j++)
         for (i = 0; i < nx; i++)
            fprintf(file, "1 5 %d %d %d %d %d %d %d %d\n",
                    i + j*(nx+1) + k*(nx+1)*(ny+1),
                    i + 1 +j*(nx+1) + k*(nx+1)*(ny+1),
                    i + 1 + (j+1)*(nx+1) + k*(nx+1)*(ny+1),
                    i + (j+1)*(nx+1) + k*(nx+1)*(ny+1),
                    i + j*(nx+1) + (k+1)*(nx+1)*(ny+1),
                    i + 1 +j*(nx+1) + (k+1)*(nx+1)*(ny+1),
                    i + 1 + (j+1)*(nx+1) + (k+1)*(nx+1)*(ny+1),
                    i + (j+1)*(nx+1) + (k+1)*(nx+1)*(ny+1));

   /* boundary will be generated by GLVis */
   fprintf(file, "\nboundary\n");
   fprintf(file, "0\n");

   /* mesh vertices */
   fprintf(file, "\nvertices\n");
   fprintf(file, "%d\n", NumOfVertices);
   fprintf(file, "%d\n", Dim);
   for (k = 0; k < nz+1; k++)
      for (j = 0; j < ny+1; j++)
         for (i = 0; i < nx+1; i++)
         {
            x = x0+i*h;
            y = y0+j*h;
            z = z0+k*h;
            fprintf(file, "%.14e %.14e %.14e\n", x, y, z);
         }

   fflush(file);
   fclose(file);
}

